package cn.wbnyua.msm.core.exception;

import cn.wbnyua.msm.util.JsonResponse;
import cn.wbnyua.msm.util.JsonUtil;
import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * 作者：wbnyua.
 * 创建时间: 2023/2/8 22:38.
 */

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public JsonResponse<String> exceptionHandler(HttpServletRequest request, Exception e){
        if ( e instanceof UnAuthException){
            String code = ((UnAuthException) e).getCode();
            String message = e.getMessage();
            return new JsonResponse<>(code,message);
        }else {
            return new JsonResponse<>("500", e.getMessage());
        }
    }

    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public JsonResponse<String> runtimeExceptionHandler(HttpServletRequest request,RuntimeExceptionHandler e){
        String code = e.getCode();
        return new JsonResponse<>(code,e.getMessage());
    }

    @ExceptionHandler(value = ForbiddenException.class)
    public ResponseEntity<JsonUtil> forbiddenException(HttpServletRequest request,ForbiddenException e){
        JsonUtil jsonUtil = new JsonUtil(e.getCode(), e.getMessage());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
        ResponseEntity<JsonUtil> response = new ResponseEntity<>(jsonUtil,headers,httpStatus);
        return response;

    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    public JsonUtil handleBeanValidation(MethodArgumentNotValidException e) {
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        String message = this.formatAllErrorMessage(errors);
        return new JsonUtil(501, message);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public JsonUtil handleConstraintViolationException(ConstraintViolationException e){

        return new JsonUtil(502,e.getMessage());
    }

    private String formatAllErrorMessage(List<ObjectError> errors){
        StringBuffer errorMsg = new StringBuffer();
        errors.forEach(error -> errorMsg.append(error.getDefaultMessage()).append(";"));
        return errorMsg.toString();
    }

}
